package model;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 * 
 * @author Michael Elgart, tyy
 *
 */
public class XMLparser extends FileParser {
    private static final String PARSE_ERROR = "Error parsing the XML";
    private static final String ACCESS_ERROR = "Error accessing the XML";
    private static final String ROW = "Row";

    /**
     * empty constructor
     */
    public XMLparser() { }
    @Override
    public void readInput (InputStream input, DataTable table) {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        Document doc = null;
        try {
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            doc = dBuilder.parse(input);
        }
        catch (SAXException e) {
            throw new ModelException(PARSE_ERROR, e);
        }
        catch (IOException e) {
            throw new ModelException(ACCESS_ERROR, e);
        }
        catch (ParserConfigurationException e) {
            throw new ModelException(PARSE_ERROR, e);
        }
        doc.getDocumentElement().normalize();

        parseDocument(table, doc);
    }
    private void parseDocument (DataTable table, Document doc) {
        //Get first row
        Element docEle = doc.getDocumentElement();
        NodeList rowList = docEle.getElementsByTagName(ROW);
        Element columnNameElement = (Element)rowList.item(0);
        // create a list of column names
        List<String> columnTags = new ArrayList<String>();
        for (int i = 1; i < columnNameElement.getChildNodes().getLength(); i += 2) {
            columnTags.add(columnNameElement.getChildNodes().item(i).getNodeName());
        }
        String[] columnNames = new String[columnTags.size()];
        for (int i = 0; i < columnTags.size(); i++) {
            columnNames[i] = getTagValue(columnTags.get(i), columnNameElement);
        }
        //construct the columns
        List<ArrayList<String>> contentStrings = initialize2DArrayList(columnNames);
        for (int i = 1; i < rowList.getLength(); i++) {
            Node rowNode = rowList.item(i);
            if (rowNode.getNodeType() == Node.ELEMENT_NODE) {

                Element rowElement = (Element) rowNode;

                for (int j = 0; j < columnTags.size(); j += 1) {
                    String data = getTagValue(columnTags.get(j), rowElement);
                    contentStrings.get(j).add(data);
                }
            }
        }
        convertColumns(table, columnNames, contentStrings);
    }
    private String getTagValue(String sTag, Element eElement) {
        NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
 
        Node nValue = (Node) nlList.item(0);
 
        return nValue.getNodeValue();
    }
}
